package org.sczfdf.utils;

import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.sczfdf.bean.CmdInfo;
import org.sczfdf.conf.GitConf;
import org.sczfdf.conf.WatchConf;
import org.sczfdf.exception.SyncException;
import org.sczfdf.listener.FileListener;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Created by cgb
 * @date 2023/2/3
 */
public class WatchUtil {

    private static final List<String> WATCH_SUFFIX;
    private static final int WATCH_INTERVAL;
    private static final List<CmdInfo> WATCH_OTHER_CMD_LIT;

    static {
        WatchConf watchConf = WatchConf.get();
        WATCH_SUFFIX = watchConf.getWatchWatchSuffix();
        WATCH_INTERVAL = watchConf.getWatchInterval();
        WATCH_OTHER_CMD_LIT = watchConf.getWatchOtherCmdLit();
    }

    public static IOFileFilter getFileFilter() {
        LogUtil.logInfo("扫描后缀:" + WATCH_SUFFIX.toString());
        if (WATCH_SUFFIX.isEmpty()) {
            return null;
        }

        IOFileFilter[] ioFileFilters = new IOFileFilter[WATCH_SUFFIX.size() + 1];
        ioFileFilters[0] = FileFilterUtils.and(
                FileFilterUtils.directoryFileFilter(),
                HiddenFileFilter.VISIBLE);

        for (int i = 0; i < WATCH_SUFFIX.size(); i++) {
            ioFileFilters[i + 1] = FileFilterUtils.and(
                    FileFilterUtils.fileFileFilter(),
                    FileFilterUtils.suffixFileFilter(WATCH_SUFFIX.get(i))
            );
        }

        return FileFilterUtils.or(ioFileFilters);
    }

    public static void watch() {
        String gitPath = GitConf.get().getGitPath();
        LogUtil.logInfo("开始监控, dir:" + gitPath + " 扫描间隔(秒):" + WATCH_INTERVAL);
        long intervalTime = TimeUnit.SECONDS.toMillis(WATCH_INTERVAL);

        IOFileFilter filter = getFileFilter();

        FileAlterationObserver observer = new FileAlterationObserver(
                gitPath,
                filter
        );

        observer.addListener(new FileListener());
        FileAlterationMonitor monitor = new FileAlterationMonitor(intervalTime, observer);
        try {
            monitor.start();
        } catch (Exception e) {
            throw new SyncException(e.getMessage());
        }
    }

    public static void executeOtherCommand() {
        if (WATCH_OTHER_CMD_LIT == null || WATCH_OTHER_CMD_LIT.isEmpty()) {
            return;
        }
        for (CmdInfo cmdInfo : WATCH_OTHER_CMD_LIT) {
            CmdUtil.cmd(cmdInfo);
        }
    }
}

